package com.shujia.spark.mllib

import org.apache.spark.ml.classification.{LogisticRegression, LogisticRegressionModel}
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object Demo6PersonClass {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession
      .builder()
      .master("local[7]")
      .appName("image")
      .config("spark.sql.shuffle.partitions", 8)
      .getOrCreate()
    import spark.implicits._
    import org.apache.spark.sql.functions._

    //读取数据
    val dataDF: DataFrame = spark
      .read
      .format("libsvm")
      .load("data/人体指标.txt")

    dataDF.groupBy($"label").count().show()

    /**
     * 将数据拆分成训练集和测试集
     */
    val Array(train, test) = dataDF.randomSplit(Array(0.8, 0.2))

    /**
     * 选择算法
     */
    val lr = new LogisticRegression()

    //将训练集带入算法训练模型
    val model: LogisticRegressionModel = lr.fit(train)

    //将测试集带入算法测试模型
    val frame: DataFrame = model.transform(test)

    frame.show()

    frame.cache()

    /**
     * 将测试集带入模型测试模型的准确率
     * 准确率：对的数量/总的数量
     * 精确率：即正确预测为正的占全部预测为正的比例
     * 召回率：即正确预测为正的占全部实际为正的比例
     */

    //准确率
    val acc: Double = frame.where($"label" === $"prediction").count().toDouble /
      frame.count()

    println(s"准确率：$acc")

    //精确率
    val p: Double = frame.where($"prediction" === 1.0 and $"label" === $"prediction").count().toDouble /
      frame.where($"prediction" === 1.0).count()

    println(s"精确率：$p")

    //召回率
    val c: Double = frame.where($"prediction" === 1.0 and $"label" === $"prediction").count().toDouble /
      frame.where($"label" === 1.0).count()

    println(s"召回率:$c")

  }

}
